#include "../include/mergeToVx.h"
#include "../include/busapi.h"
#include <stdio.h>

#define MY_INSTANCE     (1)
#define MY_CARD_TYPE	(CPCI1553)  // CPCI1553// PCCD1553//
#define BC_CHANNEL		(CHANNEL_1)
#define RT_CHANNEL		(CHANNEL_2)

int     bc_close = 0;
static  UINT                g_bc_ch_id;
static  UINT                g_rt_ch_id;
static	BT_U16BIT			base_data = 0x4000;     // Upper byte will increment on each buffer
static	int					active_buffer  = 0;
static	int					service_buffer = 1;


BT_INT _stdcall my_event_handler(BT_UINT cardnum, struct api_int_fifo *pFIFO);

void Bc_Rt_Test(void) 
{
	/*bc define*/
	API_BC_MBUF			bc_msg[2],bc_msg_rc;	  // Structures to define BC messages
	int					i;
	API_INT_FIFO		sIntFIFO1;	  // For interrupt handling
	char				c;
	int dev_num, mode;
	
	/*rt define*/
	BT_INT				status;
	API_RT_ABUF			Abuf_RT1;	  // RT address buffer structure.
	API_RT_CBUF			Cbuf_RT1SA1R; // RT control buffer structures.
	API_RT_CBUF			Cbuf_RT1SA2T;
	API_RT_MBUF_WRITE	msg_buffer_write;
	API_RT_MBUF_READ	msg_buffer_read;	
	unsigned short		cmd, sts;
	
	printf("Initializing API with BusTools_API_OpenChannel\n");
	
	/*First find the device based on type and instance*/
	dev_num = BusTools_FindDevice(MY_CARD_TYPE, MY_INSTANCE);
	if (dev_num < 0)
	{
		printf("ERROR IN BUSTOOLS_FINDDEVICE.\n");
	}
	
    /*Open the device and get the channel id*/
    mode = API_B_MODE | API_SW_INTERRUPT;  
    /*1553B protocol, use SW interrupts*/
    /*open BC channel*/
    status = BusTools_API_OpenChannel(&g_bc_ch_id, mode, dev_num, BC_CHANNEL);

	if (status == API_SUCCESS) 
	{
		/*Select External Bus*/
		printf("Bus select\n");
		status = BusTools_SetInternalBus(g_bc_ch_id, 0);
		if (status != API_SUCCESS)
		{
			printf("ERROR = %d\n",status);
		}
		
		printf("BC Init\n");
		status = BusTools_BC_Init(g_bc_ch_id, 0, BT1553_INT_END_OF_MESS, 0, 14, 12, 500000, 1);
		if (status != API_SUCCESS)
		{
			printf("ERROR = %d\n",status);
		}
		else
		{
			printf("MSG Alloc\n");
			status = BusTools_BC_MessageAlloc(g_bc_ch_id,1024);
			if (status != API_SUCCESS)
			{
				printf("ERROR = %d\n",status);
			}

			printf("MSG 0\n");
			memset(&bc_msg[0], 0, sizeof(bc_msg[0]));
			bc_msg[0].messno				= 0;		// Message number
			bc_msg[0].control = BC_CONTROL_MESSAGE;		// This is a standard BC message.
			bc_msg[0].control |= BC_CONTROL_CHANNELA;	// Send message on bus A (primary).
			bc_msg[0].control |= BC_CONTROL_BUFFERA;	// Using buffer A
			bc_msg[0].control |= BC_CONTROL_MFRAME_BEG;	// Beginning of minor frame.
			bc_msg[0].messno_next			= 1;		// Next message number, go to msg #1
			bc_msg[0].mess_command1.rtaddr	= 1;		// Command word 1, RT address
			bc_msg[0].mess_command1.subaddr = 1;		// Command word 1, Subaddress
			bc_msg[0].mess_command1.tran_rec = 0;		// Command word 1, transmit (1) or receive (0)
			bc_msg[0].mess_command1.wcount	= 0;		// Command word 1, word count, 0-31, 0=32 words
			bc_msg[0].gap_time				= 10;		// Intermessage gap time in microseconds

			/*Initialize active data*/
			for (i = 0; i < 32; i++)
			{
				bc_msg[0].data[0][i] = base_data + i;
			}
			
			base_data += 0x0300;

			/*Write the message to board memory*/			
			status = BusTools_BC_MessageWrite(g_bc_ch_id, 0, &bc_msg[0]);
			if (status != API_SUCCESS)
			{
				printf("ERROR = %d\n",status);
			} 
			
			/*Do the same thing again for the second message (1-T-2-32)*/
			printf("MSG 1\n");
			memset(&bc_msg[1], 0, sizeof(bc_msg[1]));
			bc_msg[1].messno				= 1;		// Message number
			bc_msg[1].control = BC_CONTROL_MESSAGE;		// This is a standard BC message.
			bc_msg[1].control |= BC_CONTROL_CHANNELA;	// Send message on bus A (primary).
			bc_msg[1].control |= BC_CONTROL_BUFFERA;	// Using buffer A.
			bc_msg[1].control |= BC_CONTROL_MFRAME_END;	// End of minor frame.
			bc_msg[1].control |= BC_CONTROL_INTERRUPT;	// ENABLE INTERRUPT ON THIS MESSAGE.
			bc_msg[1].messno_next			= 0;		// Next message number, go to msg #0.
			bc_msg[1].mess_command1.rtaddr	= 1;		// Command word 1, RT address
			bc_msg[1].mess_command1.subaddr = 2;		// Command word 1, Subaddress
			bc_msg[1].mess_command1.tran_rec = 1;		// Command word 1, transmit (1) or receive (0)
			bc_msg[1].mess_command1.wcount	= 0;		// Command word 1, word count, 0-31, 0=32 words
			bc_msg[1].gap_time				= 10;		// Intermessage gap time in microseconds
			
			/* Write the message to board memory*/
			status = BusTools_BC_MessageWrite(g_bc_ch_id, 1, &bc_msg[1]);
			if (status != API_SUCCESS)
			{
				printf("ERROR = %d\n",status);
			}
			
			/*Setup for our interrupt event handling functions*/
			memset(&sIntFIFO1, 0, sizeof(sIntFIFO1));
			sIntFIFO1.function       = my_event_handler;
			sIntFIFO1.iPriority      = THREAD_PRIORITY_NORMAL;
			sIntFIFO1.dwMilliseconds = INFINITE;
			sIntFIFO1.iNotification  = 0;

			/*Register for BC message events*/
			sIntFIFO1.FilterType     = EVENT_BC_MESSAGE;
			/*Enable all messages, RT1 TX SA2*/
            sIntFIFO1.FilterMask[1][1][2] = 0xFFFFFFFF;  
			/*Call the register function to register and start the thread*/
			printf("Registering event handler \n");
			status = BusTools_RegisterFunction(g_bc_ch_id, &sIntFIFO1, REGISTER_FUNCTION);
			if (status != API_SUCCESS)
			{
				printf("Error = %d.\n", status);
			}
			else
			{
				printf("Success.\n");
			}
				
		} 
		
		/*rt config*/
		status = BusTools_API_OpenChannel(&g_rt_ch_id, mode, dev_num, RT_CHANNEL);
		if (status != API_SUCCESS) 
		{
			printf("ERROR = %d\n",status);	
		}
		
		status = BusTools_SetInternalBus(g_rt_ch_id, 0);
		if (status != API_SUCCESS) 
		{
			printf("ERROR = %d\n",status);	
		}
		

		BusTools_SetVoltage(g_rt_ch_id, 19800, 0);
		
		printf("Initializing RT functionality\n");
		status = BusTools_RT_Init(g_rt_ch_id, 0);
		if (status == API_SUCCESS)
		{
			printf("Rt Success.\n");
		
			/*Setup RT address buffer for our RT (RT1)*/
			Abuf_RT1.enable_a = 1;			// Respond on bus A
			Abuf_RT1.enable_b = 1;			// Respond on bus B
			Abuf_RT1.inhibit_term_flag = 1;	// Inhibit terminal flag in status word
			Abuf_RT1.status = 0x0800;		// Set status word
			Abuf_RT1.bit_word = 0x0000;		// Set BIT word (for mode code 19)
			status = BusTools_RT_AbufWrite(g_rt_ch_id, 1, &Abuf_RT1);
			if (status != API_SUCCESS) 
			{
				printf("Error %d on BusTools_RT_AbufWrite.\n",status);
			}
			
			/*Setup a control buffer - RT1, SA1, Receive, 1 buffer*/
			/*any word count is legal*/
			Cbuf_RT1SA1R.legal_wordcount = 0xFFFFFFFF; 
			status = BusTools_RT_CbufWrite(g_rt_ch_id, 1, 1, 0, 1, &Cbuf_RT1SA1R);
			if (status != API_SUCCESS)
			{
				 printf("Error %d on BusTools_RT_CbufWrite.\n",status);	
			}
			
			/*Setup a control buffer - RT1, SA2, Transmit, 1 buffer*/
			Cbuf_RT1SA2T.legal_wordcount = 0xFFFFFFFF;  /*any word count is legal*/
			status = BusTools_RT_CbufWrite(g_rt_ch_id, 1, 2, 1, 1, &Cbuf_RT1SA2T);
			if (status != API_SUCCESS)
			{
				 printf("Error %d on BusTools_RT_CbufWrite.\n",status);
			}
			
			/*Put some data in our transmit buffer*/
			msg_buffer_write.enable = 0;		// No interrupts enabled
			msg_buffer_write.error_inj_id = 0;	// No error injection
			
			memset(&msg_buffer_write,0,sizeof(API_RT_MBUF_WRITE));//wy
			
			for (i = 0; i<32; i++)
			{
				msg_buffer_write.mess_data[i] = 0xE00 + i;
			}
				
			status = BusTools_RT_MessageWrite(g_rt_ch_id, 1, 2, 1, 0, &msg_buffer_write);
			if (status != API_SUCCESS)
			{
				printf("Error %d on BusTools_RT_MessageWrite.\n",status);
			} 
			
			/*Start the bus controller, will start list at msg #0*/
			printf(" Start BC\n");
			status = BusTools_BC_StartStop(g_bc_ch_id, 1);
			if (status != API_SUCCESS)
			{
				printf("ERROR = %d\n",status);
			}
			
			/*Now lets turn on our RT */
			printf(" Start RT\n");
			status = BusTools_RT_StartStop(g_rt_ch_id, 1);
			if (status != API_SUCCESS)
			{
				printf("Error %d on BusTools_RT_StartStop.\n",status);
			} 
		}
		
		do
		{
			printf("\nInput Q to stop RT and exit, anything else to read RT1 SA1 RCV data buffer.\n");
			scanf("%c",&c);

			if (c != 'Q') 
			{
				printf("Reading data for RT1 SA1 RCV\n");
				
				status = BusTools_RT_MessageRead(g_rt_ch_id, 1, 1, 0, 0, &msg_buffer_read);
				if (status != API_SUCCESS)
				{
					printf("ERROR READING RT MESSAGE, Error = %d\n",status);
				}
				else 
				{

					printf("RT1 SA1 RCV Data Buffer:\n");
					memcpy(&cmd, &msg_buffer_read.mess_command, sizeof(msg_buffer_read.mess_command));
					printf("Command word = %04X\n",cmd);
					for (i = 0; i < 32; i++)
					{
						printf("%04x ",msg_buffer_read.mess_data[i]);
						if (!((i+1)%8))
						{
							printf("\n");	
						}
					} 
					memcpy(&sts, &msg_buffer_read.mess_status, sizeof(msg_buffer_read.mess_status));
					printf("Status word  = %04X\n",sts);
				}
				
				status = BusTools_BC_MessageRead(g_bc_ch_id, 1, &bc_msg_rc);
				//printf("bufferID:%d\n",sIntFIFO->fifo[tail].bufferID);
				if (status == API_SUCCESS) 
				{
					for(i = 0; i < 32; i++)
					{
						printf("%04x ",bc_msg_rc.data[0][i]);
						if (!((i+1)%8))
						{
							printf("\n");	
						}
					}
				}
			}
			

		} while (c != 'Q'); 
		
		printf("Stopping RT simulation\n");
		status = BusTools_RT_StartStop(g_rt_ch_id, 0);
		if (status != API_SUCCESS)
		{
			printf("Error = %d.\n", status);	
		}
		else
		{
			printf("Stopped.\n");	
		}
		
		printf("\n BC running Hit any key to stop and exit\n");
		scanf("%c",&c);

		status = BusTools_BC_StartStop(g_bc_ch_id, 0);
		if (status != API_SUCCESS)
		{
			printf("ERROR = %d\n",status);
		}
		else
		{
			printf("Stopped.\n");	
		}
		/*Un-Register our interrupt event handling functions*/
		printf("Unregistering event handler\n");
		status = BusTools_RegisterFunction(g_bc_ch_id, &sIntFIFO1, UNREGISTER_FUNCTION);
		if (status != API_SUCCESS)
		{
			printf("Error = %d.\n", status);
		}
		else
		{
			printf("Success.\n");
		}	
		
		/*We're done Close API and board*/
		printf("Closing API \n");
		
		/*cose bc channel*/
		status = BusTools_API_Close(g_bc_ch_id);
		if (status == API_SUCCESS)
		{
			printf("Success.\n");
		}
		else
		{
			printf("FAILURE, error = %d\n", status);
		}
		
		/*close rt channel*/
		status = BusTools_API_Close(g_rt_ch_id);
		if (status == API_SUCCESS)
		{
			printf("Success.\n");
		}
		else
		{
			printf("FAILURE, error = %d\n", status);
		}
	} 
	else 
	{
		printf("FAILURE, error = %d\n", status);
	}
	printf("FINISHED.\n");
} 


/****************************************************************************
*
*  Function:  my_event_handler
*
*  Description:  Show how to register an interrupt thread and process the
*                resulting thread FIFO entries and interrupt calls.
*                This function processes the interrupt calls.
*
****************************************************************************/
BT_INT _stdcall my_event_handler(BT_UINT cardnum, struct api_int_fifo *sIntFIFO)
{
	BT_INT				tail;	           // FIFO Tail index
	//BT_INT				status, i;
	//API_BC_MBUF			bc_msg;
	
	//logMsg("---into handle---\r\n",0,0,0,0,0,0);
	   
	tail = sIntFIFO->tail_index;
	while ( tail != sIntFIFO->head_index )
	{
		if ( sIntFIFO->fifo[tail].event_type & EVENT_BC_MESSAGE )
		{
		//  Process a BC interrupt:
		 //sIntFIFO->fifo[tail].buffer_off       // Byte address of buffer
		 //sIntFIFO->fifo[tail].rtaddress        // RT address
		 //sIntFIFO->fifo[tail].transrec         // Transmit/Receive
		 //sIntFIFO->fifo[tail].subaddress       // Subaddress number
		 //sIntFIFO->fifo[tail].wordcount        // Word count
		 //sIntFIFO->fifo[tail].bufferID         // BC message number
		
		 /*Handle message received from RT1 SA2 TRANSMIT*/
		if ((sIntFIFO->fifo[tail].rtaddress  == 1) &&
			  (sIntFIFO->fifo[tail].transrec   == 1) &&
			  (sIntFIFO->fifo[tail].subaddress == 2)) 
		{
			  /*Read the second message*/
#if 0
				status = BusTools_BC_MessageRead(g_bc_ch_id, sIntFIFO->fifo[tail].bufferID, &bc_msg);
				//printf("bufferID:%d\n",sIntFIFO->fifo[tail].bufferID);
				if (status == API_SUCCESS) 
				{
					for(i = 0; i < 32; i++)
					{
						printf("%04x ",bc_msg.data[0][i]);
						if (!((i+1)%8))
						{
							printf("\n");	
						}
					}
				}
#endif
			} /*Done handling message received from RT1 SA2 TRANSMIT*/			
		}
	/*Now update and store the tail pointer*/
	tail++;                         // Next entry
	tail &= sIntFIFO->mask_index;   // Wrap the index
	sIntFIFO->tail_index = tail;    // Save the index
	}   
	   
	bc_close = 1;
	return (API_SUCCESS);
}


